#pragma once

#include <iostream>
#include <string>
#include <cstdio>
#include <jsoncpp/json/json.h>

// #define MySelf 1

const std::string blank_space_sep =  " ";
const std::string protocol_sep = "\n";

std::string Encode(const std::string& content)
{
    std::string package = std::to_string(content.size());
    package += protocol_sep;
    package += content;
    package += protocol_sep;
    return package;
}

// "len"\n"x op y"\n -->  "len"\n   "x op y"   \n
bool Decode(std::string& package, std::string* content)
{
    auto pos = package.find(protocol_sep);
    if(pos == std::string::npos) return false;

    std::string len_str = package.substr(0, pos);   // 协议报头的长度（字符串形式）
    size_t len = std::stoi(len_str);                // 有效载荷的长度（字符串形式）

    // len(package) = len_str + content_str + protocol_sep.size * 2
    size_t total_len = len_str.size() + len + protocol_sep.size() * 2;
    if(package.size() < total_len) return false;    // 接收到的报文不完整

    *content = package.substr(pos + 1, len);

    // 移除上一个报文
    package.erase(0, total_len);

    return true;
}

class Request
{
public:
    Request(int data1, int data2, char oper) 
        : x(data1), y(data2), op(oper)
    {}  

    Request() { }

    bool Serialization(std::string* out)
    {   
#ifdef MySelf
        // 构建报文的有效载荷
        // struct --> string， "x op y" --> "len"\n"x op y"\n
        std::string s = std::to_string(x) + blank_space_sep + op + blank_space_sep + std::to_string(y);
       
        *out = s;
        return true;
#else
        Json::Value root;
        root["x"] = x;
        root["op"] = op;
        root["y"] = y;
        // Json::FastWriter w;
        Json::StyledWriter w;
        *out = w.write(root);
        return true;
#endif
    }

    bool Deserialization(const std::string& in)
    {
#ifdef MySelf
        auto left = in.find(blank_space_sep);
        if(left == std::string::npos) return false;
        std::string partX = in.substr(0, left);

        auto right = in.rfind(blank_space_sep);
        if(right == std::string::npos) return false;
        std::string partY = in.substr(right + 1);

        if(left + 2 != right) return false;
        op = in[left + 1];
        x = std::stoi(partX);
        y = std::stoi(partY);
        return true;
#else
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);

        x = root["x"].asInt();
        y = root["y"].asInt();
        op = root["op"].asInt();
        return true;
#endif
    }     

    void DebugPrint()
    {
        printf("构建新请求：%d %c %d = ?\n", x, op, y);
    }  
public:
    int x;
    int y;
    char op;
};


class Response
{
public:
    Response(int ret, int c)
        : result(ret), code(c)
    {}

    Response() { }

    bool Serialization(std::string* out)
    {
#ifdef MySelf
        // 构建报文的有效载荷: "reuslt code"
        std::string s = std::to_string(result) + blank_space_sep + std::to_string(code);
        
        *out = s;
        return true;
#else
        Json::Value root;
        root["result"] = result;
        root["code"] = code;
        // Json::FastWriter w;
        Json::StyledWriter w;
        *out = w.write(root);
        return true;
#endif
    }

    bool Deserialization(const std::string& in)
    {
#ifdef MySelf
        auto pos = in.find(blank_space_sep);
        if(pos == std::string::npos) return false;
        std::string partLeft = in.substr(0, pos);
        std::string partRight = in.substr(pos + 1);

        result = std::stoi(partLeft);
        code = std::stoi(partRight);

        return true;
#else
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);
        result = root["result"].asInt();
        code = root["code"].asInt();
        return true;
#endif
    }   

    void DebugPrint()
    {
        printf("结果响应: ret: %d, code: %d\n", result, code);
    }  
public:
    int result;
    int code;   // 0: success, !0: failed
};